package com.lheia.tool

import ch.qos.logback.classic.Logger
import com.alibaba.fastjson.JSONObject
import org.apache.http.HttpEntity
import org.apache.http.NameValuePair
import org.apache.http.client.ClientProtocolException
import org.apache.http.client.config.RequestConfig
import org.apache.http.client.entity.UrlEncodedFormEntity
import org.apache.http.client.methods.CloseableHttpResponse
import org.apache.http.client.methods.HttpGet
import org.apache.http.client.methods.HttpPost
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClients
import org.apache.http.message.BasicNameValuePair
import org.apache.http.util.EntityUtils
import org.slf4j.LoggerFactory
import us.codecraft.webmagic.Spider

import java.nio.charset.Charset

/**
 * Created by XinXi-001 on 2017/11/21.
 */
class ToolHttpConnect {

    static String HTTP_METHOD_POST = "POST"
    static String HTTP_METHOD_GET = "GET"
    /** 响应超时时间，超过此时间不再读取响应,单位毫秒 **/
    private static int SOCKET_TIME_OUT = 5000
    /** 链接建立的超时时间，单位毫秒**/
    private static int CONNECT_TIME_OUT = 5000
    private final static Logger logger = LoggerFactory.getLogger(this.class)

    static getResponse(String url, Map<String, String> params, String httpMethod) {
        logger.debug("url:" + url)
        logger.debug("params:" + params)
        /** 创建默认的CloseableHttpClient实例 **/
        CloseableHttpClient httpclient = HttpClients.createDefault()
        /**
         * 设置请求次数，时间等
         */
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(SOCKET_TIME_OUT)
                .setConnectTimeout(CONNECT_TIME_OUT)
                .build();

        def httpRequest
        try {
            if (httpMethod == "POST") {
                /**
                 *   如果使用HttpPost方法提交HTTP POST请求,则需要使用HttpPost类的setEntity方法设置请求参数。
                 *   参数则必须用NameValuePair[]数组存储
                 */
                List<NameValuePair> formParams = new ArrayList<NameValuePair>()
                params.each { entry ->
                    formParams.add(new BasicNameValuePair(entry.key, entry.value))
                }
                /**
                 *  创建请求方法的实例，并指定请求URL。
                 *  如果需要发送GET请求，创建HttpGet对象；如果需要发送POST请求，创建HttpPost对象
                 */
                httpRequest = new HttpPost(url)
                UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formParams, "UTF-8")
                httpRequest.setEntity(uefEntity)
            } else if (httpMethod == "GET") {
                httpRequest = new HttpGet(appendUrlParam(url, params));
            }
            httpRequest.setConfig(requestConfig);
            /**
             * 调用CloseableHttpClient对象的execute(HttpUriRequest request)发送请求，
             * 该方法返回一个CloseableHttpResponse
             */
            CloseableHttpResponse response = httpclient.execute(httpRequest)
            int code = response.getStatusLine().getStatusCode()
            if (code == 200) {
                try {
                    HttpEntity entity = response.getEntity()
                    if (entity != null) {
                        logger.debug("请求成功")
                        def responseJson = EntityUtils.toString(entity, "UTF-8")
                        return responseJson
                    } else {
                        return false
                    }
                }
                finally {
                    response.close()
                }
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace()
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace()
        } catch (IOException e) {
            e.printStackTrace()
        } finally {
            /** 关闭连接,释放资源 **/
            try {
                httpclient.close()
            } catch (IOException e) {
                e.printStackTrace()
            }
        }
    }

    static getResponseWithJSON(url, JSONObject jsonObject) {
        logger.debug("url:" + url)
        logger.debug("params:" + jsonObject.toString())
        /** 创建默认的CloseableHttpClient实例 **/
        CloseableHttpClient httpclient = HttpClients.createDefault()
        /**
         * 设置请求次数，时间等
         */
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(SOCKET_TIME_OUT)
                .setConnectTimeout(CONNECT_TIME_OUT)
                .build();

        def httpRequest
        try {
            /**
             *   如果使用HttpPost方法提交HTTP POST请求,则需要使用HttpPost类的setEntity方法设置请求参数。
             *   参数则必须用NameValuePair[]数组存储
             */
            httpRequest = new HttpPost(url)
            StringEntity requestEntity = new StringEntity(jsonObject.toString(), Charset.forName("UTF-8"));
            requestEntity.setContentEncoding("UTF-8");
            httpRequest.setEntity(requestEntity)
            /**
             * 调用CloseableHttpClient对象的execute(HttpUriRequest request)发送请求，
             * 该方法返回一个CloseableHttpResponse
             */
            CloseableHttpResponse response = httpclient.execute(httpRequest)
            int code = response.getStatusLine().getStatusCode()
            if (code == 200) {
                try {
                    HttpEntity entity = response.getEntity()
                    if (entity != null) {
                        logger.debug("请求成功")
                        def responseJson = EntityUtils.toString(entity, "UTF-8")
                        return responseJson
                    } else {
                        logger.debug("请求失败")
                        return false
                    }
                }
                finally {
                    response.close()
                }
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace()
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace()
        } catch (IOException e) {
            e.printStackTrace()
        } finally {
            /** 关闭连接,释放资源 **/
            try {
                httpclient.close()
            } catch (IOException e) {
                e.printStackTrace()
            }
        }
    }
    /**
     * @param url
     * @param params
     * @return 返回请求数据
     */
    static getResponse(String url, Map<String, String> params) {
        return getResponse(url, params, HTTP_METHOD_POST);
    }

    /**
     *
     * @param url
     * @param params
     * @param httpMethod
     * @return 返回反序列化的对象空值返回false
     */
    static getResponseJSONWithJSON(url, JSONObject jsonObject) {
        def resultStr = ToolHttpConnect.getResponseWithJSON(url, jsonObject)
        if (resultStr) {
            return JSONObject.parse(resultStr)
        } else {
            logger.error("请求json失败")
            return false
        }
    }

    /**
     *
     * @param url
     * @param params
     * @param httpMethod
     * @return 返回反序列化的对象空值返回false
     */
    static getResponseJSON(String url, Map<String, String> params, String httpMethod) {

        def resultStr = ToolHttpConnect.getResponse(url, params, httpMethod)
        if (resultStr) {
            return JSONObject.parse(resultStr)
        } else {
            logger.error("请求json失败")
            return false
        }
    }

    static appendUrlParam(String url, params) {
        if (url.contains('?')) {
            url = url + "&"
        } else {
            url = url + "?"
        }
        params.each { entry ->
            url = url + entry.key + "=" + entry.value + "&"
        }
        return url
    }

    static main(def args){
        Spider
    }
}
